package MultiNetworkingBase;

//The Graphics Manager should handle all of the drawing
//It doesn't need to handle logic (see unit manager, and others?)

import java.awt.Font;
import java.io.IOException;
import java.util.ArrayList;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class GraphicsManager {
	private ArrayList<Drawable> drawableEntities; //Everything we are drawing
	private ArrayList<Drawable> buttonEntities; //All of the Buttons (that may have text)
	public static final int WINDOW_WIDTH = 600;
	public static final int WINDOW_HEIGHT = 400;
	public static UnicodeFont basicFont;
	
	long lastFrame; //Time at last frame
	int fps;
	long lastFPS;
	
	public GraphicsManager() {
		drawableEntities = new ArrayList<Drawable>();
		buttonEntities = new ArrayList<Drawable>();
		
		//Set up GL11
		try {
			Display.setDisplayMode(new DisplayMode(WINDOW_WIDTH, WINDOW_HEIGHT));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
		//GL11.glEnable(GL11.GL_LIGHTING);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 30, -30);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glEnable(GL11.GL_TEXTURE_2D);

		loadTextures();
	}
	
	/**
	 * Calculate the FPS and set it in the title bar
	 */
	public void updateFPS() {
		if (WarTug.getTime() - lastFPS > 1000) {
			Display.setTitle("FPS: " + fps);
			fps = 0;
			lastFPS += 1000;
		}
		fps++;
	}
	
	private void loadTextures() {
		try {
			TextureHolder.tex = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/char.png"));
			
			
			
			//Setup font. See: http://www.unicodemap.org/, if we can't get right glyphs, then add more unicode glyphs
			//Code for setting up fonts from: http://slick.cokeandcode.com/wiki/doku.php?id=unicode_font_support
			Font awtFont = new Font("Andale Mono", Font.BOLD, 24);
			basicFont = new UnicodeFont(awtFont, 24, true, false);
			basicFont.addAsciiGlyphs();
			//basicFont.addGlyphs(aNumber,aNotherNumber);  //as above, if we need more glyphs, look them up and add them here
			basicFont.getEffects().add(new ColorEffect(java.awt.Color.WHITE));
			try {
				basicFont.loadGlyphs();
			} catch (SlickException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (IOException e1) { e1.printStackTrace(); }
	}
	
	public void addDrawableEntity(Drawable d) {
		if (!(d instanceof Button)) {
			drawableEntities.add(d);
		} else {
			buttonEntities.add(d);
		}
	}
	
	public void removeDrawableEntity(Drawable d) {
		if (drawableEntities.contains(d)){
			drawableEntities.remove(d);
		} else if (buttonEntities.contains(d)){
			buttonEntities.remove(d);
		}
	}
	
	public void clearDrawableEntities() {
		//This should only be called when we change screens
		drawableEntities = new ArrayList<Drawable>();
		buttonEntities = new ArrayList<Drawable>();
	}
	
	private void drawByTexture(Drawable d) {
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		d.getTexture().bind(); //This handles the animations, by only passing back the current animation frame
		GL11.glBegin(GL11.GL_QUADS);
			GL11.glNormal3d(0, 0, 1);
			GL11.glTexCoord2d(0.0, 0.0);
			GL11.glVertex3d(d.getX(), d.getY(), 20);
			GL11.glTexCoord2d(1.0, 0.0);
			GL11.glVertex3d(d.getX() + d.getWidth(), d.getY(), 20);
			GL11.glTexCoord2d(1.0, 1.0);
			GL11.glVertex3d(d.getX() + d.getWidth(), d.getY() + d.getHeight(), 20);
			GL11.glTexCoord2d(0.0, 1.0);
			GL11.glVertex3d(d.getX(), d.getY() + d.getHeight(), 20);
		GL11.glEnd();
	}
	
	private void drawText(Button b) {
		basicFont.drawString((float)b.getX(), (float)b.getY(), b.getText(), Color.white);
	}
	
	public void renderAll() {
		//draw everything in drawableEntities and buttonEntites
		updateFPS();
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		for (Drawable d : drawableEntities) {
			drawByTexture(d);
		}
		for (Drawable d : buttonEntities) {
			if (((Button)d).getTexture()!=null) {
				drawByTexture((Button)d);
			}
			if (((Button)d).getText()!=null) {
				drawText((Button)d);
			}
		}
		Display.update();
	}
	
	//Clean up the display for application shutdown
	public void destroySelf() {
		Display.destroy();
	}
}
